// 需要C11以上版本
// 基于cJSON, 需要cJSON.h 和 cJSON.c
// 结构的大小要小于32k，offset的寻址±32k
// 数字负最小值表示无效，不参与json转换。dword/word/byte分别对应-0x80000000/-0x8000/-0x80
// 不支持混搭数组（数组内元素必须相同）

// 数组规范表达位KJList, 

// meta description stream, this is a size_t array:
// normal：	(offset << 16 | type1), name_ptr, 
// obj:	    (offset << 16 | type1), name_ptr, sub_obj_meta_ptr,
// array :  (offset << 16 | type1), name_ptr, sub_obj_meta_ptr,
// 分为obj meta 和 
// array meta ：
// normal：	type
// obj:	    type, sub_obj_meta_ptr,
// array :  type, sub_obj_meta_ptr,

#pragma once

#include "cJSON.h"
typedef size_t meta_t;

typedef struct {
    int cnt;
    void* list;
} KJList;

//#define FM_NUM_INVALID (-0x80000000)
#define KJ_DWORD_INVALID (0x7fffffff)
#define KJ_WORD_INVALID (0x7fff)
#define KJ_BYTE_INVALID (0x7f)
#define KJ_FLOAT_INVALID ((float)(-3.39e38))
// 被kg_json接受的结构成员只有：
// 1. 数字：char，byte，short，unsigned short，int， unsigned int， float
// 2. 字符串：char *（不接受char[]）
// 3. object: 子结构指针
// 4. 数组：int长度+数组指针
// 除了基本数据, 其余都是指针。
typedef enum {
    KJ_DUMMY = 0,    // 辅助成员, 不参与json转换
    KJ_PSTR,         // 字符串指针
    KJ_CHAR,
    KJ_BYTE,
    KJ_SHORT,
    KJ_USHORT,
    KJ_INT,
    KJ_FLOAT,
    KJ_OBJ,
    KJ_POBJ,        // 子结构，指针
    KJ_LIST,
    KJ_PLIST,        // 数组，指针, 数组元素是基础元素
    KJ_PJSON,       // 子json，指针： cJSON *, 针对(复杂/可变)的嵌套子结构，灵活逐步分析

    KJ_SPECIAL = 0x10, // 0x11 - 0x1f 根据不同项目自定义的特殊类型
    KJ_INT_1,       // int型 特殊类型，存储是int型，本地存储被扩大10倍, 传输转int型, 传出要除10
    KJ_INT_S,       // int型 特殊类型，存储是int型，传输转字符型
    KJ_INT_FS1,     // int型 特殊类型，存储是int型，表示的是小数精度1位的浮点数，也就是要除10，然后传输转字符型
    KJ_INT_FS2,     // int型 特殊类型，存储是int型，表示的是小数精度2位的浮点数，也就是要除100，然后传输转字符型
    KJ_INT_F1,      // int型 特殊类型，存储是int型，表示的是小数精度1位的浮点数，也就是转json要除10
    KJ_INT_F2,      // int型 特殊类型，存储是int型，表示的是小数精度2位的浮点数，也就是转json要除100
    KJ_INT_F3,      // int型 特殊类型，存储是int型，表示的是小数精度3位的浮点数，也就是转json要除1000

    KJ_END = 0x7f,
} KJ_FIELD;

//typedef struct {
//    char* name;  		   // field name
//    short type;            // 
//    short offset;          // address offset to obj instance 
//} KJ_META;
//typedef struct {
//    KJ_META* sub;     		        // field name
//    unsigned short offset;          // address offset to obj instance 
//    unsigned short type;
//} KJ_META2;

// macro -----------------------------------------------------------------------------------------------
// 得到(...)variable arguments 的个数， 最大64
#define _KJ_NTH_ARG(_1,  _2,  _3,  _4,  _5,  _6,  _7,  _8,  _9,  _10, _11, _12, _13, _14, _15, _16, _17, _18, _19,    \
    _20, _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, _31, _32, _33, _34, _35, _36, _37, _38, _39, 			\
    _40, _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, _51, _52, _53, _54, _55, _56, _57, _58, _59, 			\
	_60, _61, _62, _63, _64, n, ...) n
#define KJA_CNT(...) _KJ_NTH_ARG(__VA_ARGS__, 64, 63, 62, 61, 60,						\
	59, 58, 57, 56, 55, 54, 53, 52, 51, 50, 49, 48, 47, 46, 45, 44, 43, 42, 41, 40,   	\
	39, 38, 37, 36, 35, 34, 33, 32, 31, 30, 29, 28, 27, 26, 25, 24, 23, 22, 21, 20,   	\
	19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1 )
// 辅助宏, 分别得到结构成员相对结构开始的偏移量和大小，st - 结构名，field - 成员名
#define KJ_OFFSET(st, field) ((size_t)(&(((st *)0)->field)))
#define KJ_SIZE(st, field) (sizeof(((st *)0)->field))
// 辅助宏, 分割package参数(a, b)类型的变量, 例如 // KM_PAIR_FIRST((double, a)) => _KM_PAIR_FIRST(double, a) => double
#define _KJP_A1(a, ...) a
#define KJP_A1(pair) _KJP_A1 pair
#define _KJP_A2(a, b, ...) b
#define KJP_A2(pair) _KJP_A2 pair
#define _KJP_A3(a, b, c, ...) c
#define KJP_A3(pair) _KJP_A3 pair
#define _KJP_A4(a, b, c, d, ...) d
#define KJP_A4(pair) _KJP_A4 pair
#define _KJP_A5(a, b, c, d, e) e
#define KJP_A5(pair) _KJP_A5 pair
// 辅助宏, x 是另一个macro, 取x展开后的值的字符串而不是x本身字符串
#define _KJ_STR(x) #x
#define KJ_STR(x) _KJ_STR(x)
// 辅助宏, 拼接x，y，且x，y 是macro， 要展开后的值再连接。
#define _KJ_CAT(x, y) x##y
#define KJ_CAT(x, y) _KJ_CAT(x, y)
// 辅助宏, 计算package也就是()中参数数量，比如 KJP_CNT_V((a,b,c)) = 3
#define _KJP_CNT(...) KJA_CNT(__VA_ARGS__)
#define KJP_CNT(pack) _KJP_CNT pack

// according argument number in fd pack, select KJMETA2 or KJMETA3
#define KJMETA(st, fd) KJ_CAT(KJMETA, KJP_CNT(fd)) (st, fd)
#define KJMETA1(st, fd) KJP_A1(fd)
#define KJMETA2(st, fd) (meta_t)((KJ_OFFSET(st, KJP_A1(fd)) << 16) | KJP_A2(fd)), (meta_t)KJ_STR(KJP_A1(fd))
#define KJMETA3(st, fd) KJMETA2(st, fd), (meta_t)KJP_A3(fd)
#define KJMETA4(st, fd) KJMETA3(st, fd), (meta_t)KJP_A4(fd)
#define KJMETA5(st, fd) KJMETA4(st, fd), (meta_t)KJP_A5(fd)

//#define KJMETA_A(arr, ...) meta_t arr##_meta[] = {KJ_CAT(KJMETA_A, KJP_CNT(__VA_ARGS__))}
//#define KJMETA_A1(type) type
//#define KJMETA_A2(type, sub) type, sub

// 模拟循环算法
#define KJ_FOR1(func, st, arg)          func(st, arg), (KJ_END)
#define KJ_FOR2(func, st, arg, ...)     func(st, arg), KJ_FOR1(func, st, __VA_ARGS__)
#define KJ_FOR3(func, st, arg, ...)     func(st, arg), KJ_FOR2(func, st, __VA_ARGS__)
#define KJ_FOR4(func, st, arg, ...)     func(st, arg), KJ_FOR3(func, st, __VA_ARGS__)
#define KJ_FOR5(func, st, arg, ...)     func(st, arg), KJ_FOR4(func, st, __VA_ARGS__)
#define KJ_FOR6(func, st, arg, ...)     func(st, arg), KJ_FOR5(func, st, __VA_ARGS__)
#define KJ_FOR7(func, st, arg, ...)     func(st, arg), KJ_FOR6(func, st, __VA_ARGS__)
#define KJ_FOR8(func, st, arg, ...)     func(st, arg), KJ_FOR7(func, st, __VA_ARGS__)
#define KJ_FOR9(func, st, arg, ...)     func(st, arg), KJ_FOR8(func, st, __VA_ARGS__)
#define KJ_FOR10(func, st, arg, ...)    func(st, arg), KJ_FOR9(func, st, __VA_ARGS__)
#define KJ_FOR11(func, st, arg, ...)    func(st, arg), KJ_FOR10(func, st, __VA_ARGS__)
#define KJ_FOR12(func, st, arg, ...)    func(st, arg), KJ_FOR11(func, st, __VA_ARGS__)
#define KJ_FOR13(func, st, arg, ...)    func(st, arg), KJ_FOR12(func, st, __VA_ARGS__)
#define KJ_FOR14(func, st, arg, ...)    func(st, arg), KJ_FOR13(func, st, __VA_ARGS__)
#define KJ_FOR15(func, st, arg, ...)    func(st, arg), KJ_FOR14(func, st, __VA_ARGS__)
#define KJ_FOR16(func, st, arg, ...)    func(st, arg), KJ_FOR15(func, st, __VA_ARGS__)
#define KJ_FOR17(func, st, arg, ...)    func(st, arg), KJ_FOR16(func, st, __VA_ARGS__)
#define KJ_FOR18(func, st, arg, ...)    func(st, arg), KJ_FOR17(func, st, __VA_ARGS__)
#define KJ_FOR19(func, st, arg, ...)    func(st, arg), KJ_FOR18(func, st, __VA_ARGS__)
#define KJ_FOR20(func, st, arg, ...)    func(st, arg), KJ_FOR19(func, st, __VA_ARGS__)
#define KJ_FOR21(func, st, arg, ...)    func(st, arg), KJ_FOR20(func, st, __VA_ARGS__)
#define KJ_FOR22(func, st, arg, ...)    func(st, arg), KJ_FOR21(func, st, __VA_ARGS__)
#define KJ_FOR23(func, st, arg, ...)    func(st, arg), KJ_FOR22(func, st, __VA_ARGS__)
#define KJ_FOR24(func, st, arg, ...)    func(st, arg), KJ_FOR23(func, st, __VA_ARGS__)
#define KJ_FOR25(func, st, arg, ...)    func(st, arg), KJ_FOR24(func, st, __VA_ARGS__)
#define KJ_FOR26(func, st, arg, ...)    func(st, arg), KJ_FOR25(func, st, __VA_ARGS__)
#define KJ_FOR27(func, st, arg, ...)    func(st, arg), KJ_FOR26(func, st, __VA_ARGS__)
#define KJ_FOR28(func, st, arg, ...)    func(st, arg), KJ_FOR27(func, st, __VA_ARGS__)
#define KJ_FOR29(func, st, arg, ...)    func(st, arg), KJ_FOR28(func, st, __VA_ARGS__)
#define KJ_FOR30(func, st, arg, ...)    func(st, arg), KJ_FOR29(func, st, __VA_ARGS__)
#define KJ_FOR31(func, st, arg, ...)    func(st, arg), KJ_FOR30(func, st, __VA_ARGS__)
#define KJ_FOR32(func, st, arg, ...)    func(st, arg), KJ_FOR31(func, st, __VA_ARGS__)
#define KJ_FOR33(func, st, arg, ...)    func(st, arg), KJ_FOR32(func, st, __VA_ARGS__)
#define KJ_FOR34(func, st, arg, ...)    func(st, arg), KJ_FOR33(func, st, __VA_ARGS__)
#define KJ_FOR35(func, st, arg, ...)    func(st, arg), KJ_FOR34(func, st, __VA_ARGS__)
#define KJ_FOR36(func, st, arg, ...)    func(st, arg), KJ_FOR35(func, st, __VA_ARGS__)
#define KJ_FOR37(func, st, arg, ...)    func(st, arg), KJ_FOR36(func, st, __VA_ARGS__)
#define KJ_FOR38(func, st, arg, ...)    func(st, arg), KJ_FOR37(func, st, __VA_ARGS__)
#define KJ_FOR39(func, st, arg, ...)    func(st, arg), KJ_FOR38(func, st, __VA_ARGS__)
#define KJ_FOR40(func, st, arg, ...)    func(st, arg), KJ_FOR39(func, st, __VA_ARGS__)
#define KJ_FOR41(func, st, arg, ...)    func(st, arg), KJ_FOR40(func, st, __VA_ARGS__)
#define KJ_FOR42(func, st, arg, ...)    func(st, arg), KJ_FOR41(func, st, __VA_ARGS__)
#define KJ_FOR43(func, st, arg, ...)    func(st, arg), KJ_FOR42(func, st, __VA_ARGS__)
#define KJ_FOR44(func, st, arg, ...)    func(st, arg), KJ_FOR43(func, st, __VA_ARGS__)
#define KJ_FOR45(func, st, arg, ...)    func(st, arg), KJ_FOR44(func, st, __VA_ARGS__)
#define KJ_FOR46(func, st, arg, ...)    func(st, arg), KJ_FOR45(func, st, __VA_ARGS__)
#define KJ_FOR47(func, st, arg, ...)    func(st, arg), KJ_FOR46(func, st, __VA_ARGS__)
#define KJ_FOR48(func, st, arg, ...)    func(st, arg), KJ_FOR47(func, st, __VA_ARGS__)
#define KJ_FOR49(func, st, arg, ...)    func(st, arg), KJ_FOR48(func, st, __VA_ARGS__)
#define KJ_FOR50(func, st, arg, ...)    func(st, arg), KJ_FOR49(func, st, __VA_ARGS__)
#define KJ_FOR51(func, st, arg, ...)    func(st, arg), KJ_FOR50(func, st, __VA_ARGS__)
#define KJ_FOR52(func, st, arg, ...)    func(st, arg), KJ_FOR51(func, st, __VA_ARGS__)
#define KJ_FOR53(func, st, arg, ...)    func(st, arg), KJ_FOR52(func, st, __VA_ARGS__)
#define KJ_FOR54(func, st, arg, ...)    func(st, arg), KJ_FOR53(func, st, __VA_ARGS__)
#define KJ_FOR55(func, st, arg, ...)    func(st, arg), KJ_FOR54(func, st, __VA_ARGS__)
#define KJ_FOR56(func, st, arg, ...)    func(st, arg), KJ_FOR55(func, st, __VA_ARGS__)
#define KJ_FOR57(func, st, arg, ...)    func(st, arg), KJ_FOR56(func, st, __VA_ARGS__)
#define KJ_FOR58(func, st, arg, ...)    func(st, arg), KJ_FOR57(func, st, __VA_ARGS__)
#define KJ_FOR59(func, st, arg, ...)    func(st, arg), KJ_FOR58(func, st, __VA_ARGS__)
#define KJ_FOR60(func, st, arg, ...)    func(st, arg), KJ_FOR59(func, st, __VA_ARGS__)
#define KJ_FOR61(func, st, arg, ...)    func(st, arg), KJ_FOR60(func, st, __VA_ARGS__)
#define KJ_FOR62(func, st, arg, ...)    func(st, arg), KJ_FOR61(func, st, __VA_ARGS__)
#define KJ_FOR63(func, st, arg, ...)    func(st, arg), KJ_FOR62(func, st, __VA_ARGS__)
#define KJ_FOR64(func, st, arg, ...)    func(st, arg), KJ_FOR63(func, st, __VA_ARGS__)

// 生成名字为 结构名_meta 的数组，数组记录每个成员的meta信息
#define KJ_METAS(st, ...) meta_t st##_meta[] = {KJ_CAT(KJ_FOR, KJA_CNT(__VA_ARGS__)) (KJMETA, st, __VA_ARGS__)}




extern int KgList2Json(cJSON* node, KJList* arr, const meta_t* meta);
extern int KgStruct2Json(cJSON* node, void* st, const meta_t* metas);
extern int KgJson2List(cJSON* node, KJList* arr, const meta_t* meta);
extern int KgJson2Struct(cJSON* node, void* st, const meta_t* metas);
extern meta_t* ZqMetasTrim(const meta_t* pOrgMeta, int cnt, const char* names[]);
extern meta_t* ZqMetasFind(const meta_t* pOrgMeta, const char* key);
//extern int KgJson2Struct(cJSON* node, void* obj, const KJ_META_T* metas);
//extern int KgJson2List(cJSON* node, void* array, const KJ_META_T* metas);
//extern KJ_META_T* ZqMetasTrim(const KJ_META_T* pOrgMeta, int cnt, char* names[]);


